home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 7
/
Night Owl Shareware (NOPV7)(Night Owl Publisher Inc.)(1992).bin
/
038a
/
bash1_12.arj
/
BASH1-12.TAR
/
bash-1.12
/
builtins
/
declare.def
< prev
next >
Wrap
Text File
|
1991-11-07
|
7KB
|
279 lines
This file is declare.def, from which is created declare.c.
It implements the builtins "declare" and "local" in Bash.
Copyright (C) 1987, 1989, 1991 Free Software Foundation, Inc.
This file is part of GNU Bash, the Bourne Again SHell.
Bash is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 1, or (at your option) any later
version.
Bash is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License along
with Bash; see the file COPYING. If not, write to the Free Software
Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
$PRODUCES declare.c
$BUILTIN declare
$FUNCTION declare_builtin
$SHORT_DOC declare [-[frxi]] name[=value] ...
Declare variables and/or give them attributes. If no NAMEs are
given, then display the values of variables instead.
The flags are:
-f to select from among function names only,
-r to make NAMEs readonly,
-x to make NAMEs export,
-i to make NAMEs have the `integer' attribute set.
Variables with the integer attribute have arithmetic evaluation (see
`let') done when the variable is assigned to.
Using `+' instead of `-' turns off the given attribute instead. When
used in a function, makes NAMEs local, as with the `local' command.
$END
$BUILTIN typeset
$FUNCTION declare_builtin
$SHORT_DOC typeset [-[frxi]] name[=value] ...
Obsolete. See `declare'.
$END
#include <stdio.h>
#include "../shell.h"
static int declare_internal ();
/* Declare or change variable attributes. */
int
declare_builtin (list)
register WORD_LIST *list;
{
return (declare_internal (list, 0));
}
$BUILTIN local
$FUNCTION local_builtin
$SHORT_DOC local name[=value] ...
Create a local variable called NAME, and give it VALUE. LOCAL
can only be used within a function; it makes the variable NAME
have a visible scope restricted to that function and its children.
$END
int
local_builtin (list)
register WORD_LIST *list;
{
extern int variable_context;
if (variable_context)
return (declare_internal (list, 1));
else
{
builtin_error ("Can only be used in a function");
return (EXECUTION_FAILURE);
}
}
/* The workhorse function. */
static int
declare_internal (list, no_modifiers)
register WORD_LIST *list;
int no_modifiers;
{
extern int variable_context, array_needs_making;
int flags_on = 0, flags_off = 0;
int any_failed = 0;
while (list)
{
register char *t = list->word->word;
int *flags;
if (strcmp (t, "--") == 0)
{
list = list->next;
break;
}
if (*t != '+' && *t != '-')
break;
if (no_modifiers)
{
builtin_error ("Modifiers not allowed");
return (EXECUTION_FAILURE);
}
if (*t == '+')
flags = &flags_off;
else
flags = &flags_on;
t++;
while (*t)
{
if (*t == 'f')
*flags |= att_function, t++;
else if (*t == 'x')
*flags |= att_exported, t++, array_needs_making = 1;
else if (*t == 'r')
*flags |= att_readonly, t++;
else if (*t == 'i')
*flags |= att_integer, t++;
else
{
builtin_error ("unknown option: `-%c'", *t);
return (EXECUTION_FAILURE);
}
}
list = list->next;
}
/* If there are no more arguments left, then we just want to show
some variables. */
if (!list)
{
/* If we didn't allow modifiers, then this is the `local' command.
Perhaps the flag should be called `local_command' instead of
`no_modifiers'. At any rate, only show local variables defined
at this context level. */
if (no_modifiers)
{
register SHELL_VAR **vlist;
register int i;
vlist = map_over (variable_in_context, shell_variables);
if (vlist)
{
for (i = 0; vlist[i]; i++)
print_assignment (vlist[i]);
free (vlist);
}
}
else
{
if (!flags_on)
set_builtin ((WORD_LIST *)NULL);
else
set_or_show_attributes ((WORD_LIST *)NULL, flags_on);
}
fflush (stdout);
return (EXECUTION_SUCCESS);
}
/* There are arguments left, so we are making variables. */
while (list)
{
char *value, *name = savestring (list->word->word);
int offset = assignment (name);
if (offset)
{
name[offset] = '\0';
value = name + offset + 1;
}
else
{
value = "";
}
/* If VARIABLE_CONTEXT has a non-zero value, then we are executing
inside of a function. This means we should make local variables,
not global ones. */
if (variable_context)
make_local_variable (name);
/* If we are declaring a function, then complain about it in some way.
We don't let people make functions by saying `typeset -f foo=bar'. */
/* There should be a way, however, to let people look at a particular
function definition by saying `typeset -f foo'. */
if (flags_on & att_function)
{
if (offset)
{
builtin_error ("Can't use `-f' to make functions");
return (EXECUTION_FAILURE);
}
else
{
SHELL_VAR *find_function (), *funvar;
funvar = find_function (name);
if (funvar)
{
extern char *named_function_string ();
char *result = named_function_string
(name, (COMMAND *)function_cell (funvar), 1);
printf ("%s\n", result);
}
else
any_failed++;
goto hack_next_variable;
}
}
else
{
SHELL_VAR *var;
var = find_variable (name);
if (!var)
var = bind_variable (name, "");
/* We are not allowed to rebind readonly variables that
already are readonly unless we are turning off the
readonly bit. */
if (flags_off & att_readonly)
flags_on &= ~att_readonly;
if (value && readonly_p (var) && (!(flags_off & att_readonly)))
{
builtin_error ("%s: readonly variable", name);
any_failed++;
goto hack_next_variable;
}
var->attributes |= flags_on;
var->attributes &= ~flags_off;
if (offset)
{
free (var->value);
if (integer_p (var))
{
long val, evalexp ();
char *itos ();
val = evalexp (value);
var->value = itos ((int)val);
}
else
var->value = savestring (value);
}
}
stupidly_hack_special_variables (name);
hack_next_variable:
free (name);
list = list->next;
}
return ((!any_failed) ? EXECUTION_SUCCESS : EXECUTION_FAILURE);
}